package com.paddyi.security;

import com.paddyi.jwt.JwtConfigProperty;
import com.paddyi.jwt.JwtUtil;
import com.paddyi.commons.http.SsoHttpResult;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 登陆成功调用,在这里生成token，并将token写入redis，redis的key和value均为userId
 * 若想灵活控制权限，可将value替换为角色所拥有的资源，client端校验时通过userId从
 * redis取出资源进行比对
 * @author paddy
 * @since 2019-04-26 04:34:10
 */
@Component
public class MySuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    @Autowired
    private JwtConfigProperty jwtConfig;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Value("${jwt.serverExpirationMinute}")
    String serverExpirationMinute;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException {
        String redirectUrl = request.getParameter("redirectUrl");
        String tokenHead = this.jwtConfig.getTokenHead();
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        String userIdAndRoles = authorities.iterator().next().toString();
        // 将资源信息存入redis,时间比jwt过期时间长一分钟，防止bug
        stringRedisTemplate.opsForValue().set(userIdAndRoles, userIdAndRoles, Long.valueOf(serverExpirationMinute) + 1, TimeUnit.MINUTES);
        //生成token并写入httpheader和cookie
        String serverToken = jwtUtil.generateToken(userIdAndRoles,true);
        String clientToken = jwtUtil.generateToken(userIdAndRoles,false);
        response.setContentType("text/html;charset=UTF-8");
        Cookie cookie = new Cookie(this.jwtConfig.getHeader(), tokenHead + serverToken);
        response.addCookie(cookie);
        ObjectMapper mapper = new ObjectMapper();
        String data = mapper.writeValueAsString(SsoHttpResult.resultToken(tokenHead + clientToken, redirectUrl));
        response.getWriter().write(data);
    }
}
